﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;

using BEX.Core.Exchange;
using BEX.Core;
using BEX.DataAccess;

namespace AutomatedTesting
{
    [TestClass]
    public class TickRetrievalAccuracy
    {
        [TestMethod]
        public void Verify_NextConsecutiveTick()
        {
            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {
                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {
                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _t = TickDAL.GetCurrentTick(_e, _p);

                        if (_t == null)
                        {
                            continue;
                        }
                        var _random = TickDAL.GetPreviousTick(_e, _t);

                        Assert.IsNotNull(_random);

                        Assert.IsTrue(_random.ExchangeSource == _e);
                        Assert.IsTrue(_random.Currency.Base == _b);
                        Assert.IsTrue(_random.Currency.Counter == _c);

                        var _next = TickDAL.GetNextConsecutiveTick(_e, _random);

                        Assert.IsNotNull(_next);
                        Assert.IsTrue(_next.Id == _t.Id);

                        var queryString = "SELECT TOP 1 [ID], [UTC_TIME], [ASK], [BID], [EXCHANGE_ID], [COUNTER_CURRENCY_ID], [BASE_CURRENCY_ID], [SPOT]  FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " AND [ID] > "
                                            + _random.Id + " ORDER BY [ID]";

                        var _ref = new Tick();

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {

                                    _ref.Id = Convert.ToInt32(reader[0]);
                                    _ref.Ask = Convert.ToInt32(reader[2]);
                                    _ref.Bid = Convert.ToInt32(reader[3]);
                                    _ref.ExchangeSource = (ExchangeType)(Convert.ToInt32(reader[4]));
                                    _ref.Currency = new CurrencyPair() { Base = (CurrencyType)(Convert.ToInt32(reader[6])), Counter = (CurrencyType)(Convert.ToInt32(reader[5])) };
                                    _ref.Spot = Convert.ToInt32(reader[7]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_ref.Spot > 0);
                        Assert.IsTrue(_ref.Id == _next.Id);
                        Assert.IsTrue(_ref.Bid == _next.Bid);
                        Assert.IsTrue(_ref.Ask == _next.Ask);
                        Assert.IsTrue(_ref.ExchangeSource == _next.ExchangeSource);
                        Assert.IsTrue(_ref.Currency.Base == _next.Currency.Base);
                        Assert.IsTrue(_ref.Currency.Counter == _next.Currency.Counter);
                        Assert.IsTrue(_ref.Spot == _next.Spot);
                    }
                }
            }
        }

        [TestMethod]
        public void Verify_GetCurrentTick()
        {
            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {
                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {
                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _current = TickDAL.GetCurrentTick(_e, _p);

                        if (_current == null)
                        {
                            continue;
                        }
                        Assert.IsTrue(_current.ExchangeSource == _e);
                        Assert.IsTrue(_current.Currency.Base == _b);
                        Assert.IsTrue(_current.Currency.Counter == _c);

                        var queryString = "SELECT TOP 1 [ID], [UTC_TIME], [ASK], [BID], [EXCHANGE_ID], [COUNTER_CURRENCY_ID], [BASE_CURRENCY_ID], [SPOT]  FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " ORDER BY [ID] DESC";

                        var _ref = new Tick();

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {

                                    _ref.Id = Convert.ToInt32(reader[0]);
                                    _ref.Ask = Convert.ToInt32(reader[2]);
                                    _ref.Bid = Convert.ToInt32(reader[3]);
                                    _ref.ExchangeSource = (ExchangeType)(Convert.ToInt32(reader[4]));
                                    _ref.Currency = new CurrencyPair() { Base = (CurrencyType)(Convert.ToInt32(reader[6])), Counter = (CurrencyType)(Convert.ToInt32(reader[5])) };
                                    _ref.Spot = Convert.ToInt32(reader[7]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_ref.Spot > 0);
                        Assert.IsTrue(_ref.Id == _current.Id);
                        Assert.IsTrue(_ref.Bid == _current.Bid);
                        Assert.IsTrue(_ref.Ask == _current.Ask);
                        Assert.IsTrue(_ref.ExchangeSource == _current.ExchangeSource);
                        Assert.IsTrue(_ref.Currency.Base == _current.Currency.Base);
                        Assert.IsTrue(_ref.Currency.Counter == _current.Currency.Counter);
                        Assert.IsTrue(_ref.Spot == _current.Spot);
                    }
                }
            }
        }

        [TestMethod]
        public void Verify_GetCurrentSpot()
        {
            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {
                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {
                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _current = TickDAL.GetCurrentSpot(_e, _p);

                        if (_current == null)
                        {
                            continue;
                        }
                        Assert.IsTrue(_current.ExchangeSource == _e);
                        Assert.IsTrue(_current.Currency.Base == _b);
                        Assert.IsTrue(_current.Currency.Counter == _c);


                        var queryString = "SELECT TOP 1 [ID], [UTC_TIME], [ASK], [BID], [EXCHANGE_ID], [COUNTER_CURRENCY_ID], [BASE_CURRENCY_ID], [SPOT]  FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " ORDER BY [ID] DESC";

                        var _ref = new Tick();

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {
                                    _ref.Id = Convert.ToInt32(reader[0]);
                                    _ref.Ask = Convert.ToInt32(reader[2]);
                                    _ref.Bid = Convert.ToInt32(reader[3]);
                                    _ref.ExchangeSource = (ExchangeType)(Convert.ToInt32(reader[4]));
                                    _ref.Currency = new CurrencyPair() { Base = (CurrencyType)(Convert.ToInt32(reader[6])), Counter = (CurrencyType)(Convert.ToInt32(reader[5])) };
                                    _ref.Spot = Convert.ToInt32(reader[7]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_ref.Spot > 0);
                        Assert.IsTrue(_ref.Id == _current.Id);
                        Assert.IsTrue(_ref.Bid == _current.Bid);
                        Assert.IsTrue(_ref.Ask == _current.Ask);
                        Assert.IsTrue(_ref.ExchangeSource == _current.ExchangeSource);
                        Assert.IsTrue(_ref.Currency.Base == _current.Currency.Base);
                        Assert.IsTrue(_ref.Currency.Counter == _current.Currency.Counter);
                        Assert.IsTrue(_ref.Spot == _current.Spot);
                    }
                }
            }
        }

        [TestMethod]
        public void Verify_GetPreviousTick()
        {
            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {

                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {

                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _current = TickDAL.GetCurrentTick(_e, _p);

                        if (_current == null)
                        {
                            continue;
                        }
                        Assert.IsTrue(_current.ExchangeSource == _e);
                        Assert.IsTrue(_current.Currency.Base == _b);
                        Assert.IsTrue(_current.Currency.Counter == _c);

                        var _previous = TickDAL.GetPreviousTick(_e, _current);

                        Assert.IsNotNull(_previous);

                        Assert.IsTrue(_previous.ExchangeSource == _e);
                        Assert.IsTrue(_previous.Currency.Base == _b);
                        Assert.IsTrue(_previous.Currency.Counter == _c);

                        var queryString = "SELECT TOP 1 [ID], [UTC_TIME], [ASK], [BID], [EXCHANGE_ID], [COUNTER_CURRENCY_ID], [BASE_CURRENCY_ID], [SPOT]  FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " AND [ID] < "
                                            + _current.Id + " ORDER BY [ID] DESC";

                        var _ref = new Tick();

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {
                                    _ref.Id = Convert.ToInt32(reader[0]);
                                    _ref.Ask = Convert.ToInt32(reader[2]);
                                    _ref.Bid = Convert.ToInt32(reader[3]);
                                    _ref.ExchangeSource = (ExchangeType)(Convert.ToInt32(reader[4]));
                                    _ref.Currency = new CurrencyPair() { Base = (CurrencyType)(Convert.ToInt32(reader[6])), Counter = (CurrencyType)(Convert.ToInt32(reader[5])) };
                                    _ref.Spot = Convert.ToInt32(reader[7]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_ref.Spot > 0);
                        Assert.IsTrue(_ref.Id == _previous.Id);
                        Assert.IsTrue(_ref.Bid == _previous.Bid);
                        Assert.IsTrue(_ref.Ask == _previous.Ask);
                        Assert.IsTrue(_ref.ExchangeSource == _previous.ExchangeSource);
                        Assert.IsTrue(_ref.Currency.Base == _previous.Currency.Base);
                        Assert.IsTrue(_ref.Currency.Counter == _previous.Currency.Counter);
                        Assert.IsTrue(_ref.Spot == _previous.Spot);
                    }
                }
            }
        }

        [TestMethod]
        public void Verify_GetMaxSpot()
        {
            var _timeSpan = 157680000;

            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {
                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {
                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _last = TickDAL.GetCurrentTick(_e, _p);

                        if (_last == null)
                        {
                            continue;
                        }
                        Assert.IsTrue(_last.ExchangeSource == _e);
                        Assert.IsTrue(_last.Currency.Base == _b);
                        Assert.IsTrue(_last.Currency.Counter == _c);

                        var _max = TickDAL.GetMaximumSpot(_e, _last, _timeSpan);

                        Assert.IsNotNull(_max);

                        var queryString = "SELECT TOP 1 [SPOT] FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " ORDER BY [SPOT] DESC";

                        var _altValue = -1;

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {
                                    _altValue = Convert.ToInt32(reader[0]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_altValue > 0);


                        Assert.IsTrue(_altValue == _max.Value);
                    }
                }
            }
        }

        [TestMethod]
        public void Verify_GetMinSpot()
        {
            var _timeSpan = 157680000;

            foreach (ExchangeType _e in Enum.GetValues(typeof(ExchangeType)).Cast<ExchangeType>())
            {
                if (_e == ExchangeType.UNKNOWN)
                {
                    continue;
                }
                var _base = ExchangeDAL.GetSupportedBaseCurrencies(_e);


                foreach (CurrencyType _b in _base)
                {
                    var _counter = ExchangeDAL.GetSupportedCounterCurrencies(_e, _b);

                    foreach (CurrencyType _c in _counter)
                    {
                        CurrencyPair _p = new CurrencyPair();
                        _p.Base = _b;
                        _p.Counter = _c;

                        var _last = TickDAL.GetCurrentTick(_e, _p);

                        if (_last == null)
                        {
                            continue;
                        }

                        Assert.IsTrue(_last.ExchangeSource == _e);
                        Assert.IsTrue(_last.Currency.Base == _b);
                        Assert.IsTrue(_last.Currency.Counter == _c);

                        var _min = TickDAL.GetMinSpot(_e, _last, _timeSpan);

                        Assert.IsNotNull(_min);

                        var queryString = "SELECT TOP 1 [SPOT] FROM [EXCHANGE_TICK] 	WHERE [EXCHANGE_ID] = " + ((int)_e).ToString() + "	AND [BASE_CURRENCY_ID] = " + ((int)_b).ToString() + " AND [COUNTER_CURRENCY_ID] = "
                                            + ((int)_c).ToString() + " ORDER BY [SPOT]";

                        var _altValue = -1;

                        using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["BEX.Data.Properties.Settings.BTC_SMSConnectionString"].ConnectionString))
                        {
                            var command = new SqlCommand(
                                queryString, connection);
                            connection.Open();

                            var reader = command.ExecuteReader();
                            try
                            {
                                while (reader.Read())
                                {
                                    _altValue = Convert.ToInt32(reader[0]);
                                }
                            }
                            finally
                            {
                                reader.Close();
                            }
                        }

                        Assert.IsTrue(_altValue > 0);


                        Assert.IsTrue(_altValue == _min.Value);
                    }
                }
            }
        }
    }
}
